#ifndef _BOOTPROTO_H_
#define _BOOTPROTO_H_

#include "except.h"

class IPFormatException : public FatalError
{
public:
  IPFormatException() : FatalError()
  {}
  virtual void print()
  { std::cerr << what() << std::endl; }
  virtual std::string what()
  { return "Invalid format for ip address. should be \"nn.nn.nn.nn\""; }
  virtual ~IPFormatException()
  {}
};
  


class BootProto
{
 public:
  BootProto(std::string type) : __type(type)
  {}
  
  virtual void set_type(std::string type)
  {
    __type=type;
  }
  
  virtual std::string get_type()
  {
      return __type;
  }
  
  virtual void output(std::ofstream& file) = 0;
  
  virtual void echo()=0;

  virtual ~BootProto() {}
 private:
  std::string __type;
};

class Dhcp : public BootProto
{
public:
  Dhcp() :  BootProto("DHCP")
  {}

  virtual void output(std::ofstream& file)
  { 
    file << "BOOTPROTO=dhcp" << std::endl;
  }

  virtual void echo()
  {
    std::cout << "BOOTPROTO=dhcp" << std::endl;
  }
  virtual ~Dhcp(){}
};


class Bootp : public BootProto
{
public:
  Bootp() :  BootProto("BOOTP")
  {}

  virtual void output(std::ofstream& file)
  { 
    file << "BOOTPROTO=bootp" << std::endl;
  }

  virtual void echo()
  {
    std::cout << "BOOTPROTO=bootp" << std::endl;
  }
  virtual ~Bootp() {}
};

class Static_ip : public BootProto
{
public:
  Static_ip(std::string ip, std::string gateway, std::string netmask)
    :  BootProto("STATIC"), __ip(ip), __gateway(gateway), __netmask(netmask), 
       __has_gw(true), __has_nm(true)
  {}

  Static_ip(std::string ip, std::string gateway)
    :  BootProto("STATIC"), __ip(ip), __gateway(gateway), __netmask(),
       __has_gw(true), __has_nm(false)
  {}

  Static_ip(std::string ip)
    :  BootProto("STATIC"), __ip(ip), __gateway(), __netmask(),
       __has_gw(false), __has_nm(false)
  {}
  
  virtual void echo()
  { 
    std::cout << "BOOTPROTO=none" << std::endl
	      << "IPADDR="        << get_ip() << std::endl
	      << "NETMASK="       << get_netmask() << std::endl
	      << "GATEWAY="       << get_gateway() << std::endl;     
  }

  virtual void output(std::ofstream& file)
  { 
    file << "BOOTPROTO=none" << std::endl
	 << "IPADDR="        << get_ip() << std::endl
	 << "NETMASK="       << get_netmask() << std::endl
	 << "GATEWAY="       << get_gateway() << std::endl;     
  }

  std::string get_ip()
  {
    return __ip;
  }

  std::string get_gateway()
  {
    if(!has_gateway())
      {
	// guess gw.  if ip us aa.bb.cc.dd then guess gw is aa.bb.cc.1
	std::string tmp=get_ip();
	unsigned loc=tmp.rfind('.',tmp.length());
	if(loc==std::string::npos)
	  {
	    std::cerr <<  "Error: " << tmp << std::endl;
	    IPFormatException exc;
	    throw exc;
	  }
	std::string gw=tmp.substr(0,loc+1);
	gw+= "1";
	__gateway=gw;
	__has_gw=true;
      }
    return __gateway;	
  }		
  
  std::string get_netmask()
  {
    if(!has_netmask())
      {
	// guess netmask. 255.255.255.0 is a good guess
	
	    __netmask="255.255.255.0";
	    __has_nm=true;
      }
    return __netmask;
  }
  
  bool has_gateway()
  { return __has_gw; }

  bool has_netmask()
  { return __has_nm; }

  virtual void set_ip(std::string ip)
  {
    __ip=ip;
  }

  virtual void set_gateway(std::string gateway)
  {
    __gateway=gateway;
    __has_gw=true;
  }

  virtual void set_netmask(std::string netmask)
  {
    __netmask=netmask;
    __has_nm=true;
  }

virtual ~Static_ip() {}

private:
	  std::string __ip;
  std::string __gateway;
  std::string __netmask;
  bool __has_gw;
  bool __has_nm;

};


#endif
